//
// Created by Dinger on 2021/9/18.
//

#include "../Header files/grammar.h"

Grammar::Grammar() {

}

Grammar::Grammar(string fileName, string beginSymbolName) {
    _legalSymbolNames = map<string, bool>{{"S",           false},
                                          {"1S",          false},
                                          {"2S",          false},
                                          {"Assignment",  false},
                                          {"Conditional", false},
                                          {"WS",          false},
                                          {"Compound",    false},
                                          {"Variable",    false},
                                          {"Arithmetic",  false},
                                          {"Relational",  false},
                                          {"1A",          false},
                                          {"Item",        false},
                                          {"Factor",      false},
                                          {"1I",          false},
                                          {"Constant",    false},
                                          {"RelationC",   false},
                                          {"TAG",         false},
                                          {"Integer",     false},
                                          {"VarDef",      false},
                                          {"VarDList",    false},
                                          {"1VarDList",   false},
                                          {"VarDState",   false},
                                          {"VarList",     false},
                                          {"Type",        false},
                                          {"INTEGER",     true},
                                          {"IF",          true},
                                          {"THEN",        true},
                                          {"ELSE",        true},
                                          {"BEGIN",       true},
                                          {"WHILE",       true},
                                          {"DO",          true},
                                          {"END",         true},
                                          {"VAR",         true},
                                          {"+",           true},
                                          {"-",           true},
                                          {"*",           true},
                                          {"/",           true},
                                          {";",           true},
                                          {":=",          true},
                                          {":",           true},
                                          {"(",           true},
                                          {")",           true},
                                          {"<",           true},
                                          {"<=",          true},
                                          {"==",          true},
                                          {">",           true},
                                          {">=",          true},
                                          {"<>",          true},
                                          {"?",           false}};
    _beginSymbolName = beginSymbolName;
    readFile(fileName);
}

void Grammar::readFile(string fileName) {
    ifstream codeFile1(fileName);
    string readWord;
    vector<int> oneRow;
    vector<string> sentencesString;
    if (!codeFile1.is_open()) {
        cout << "Error opening file";
        exit(1);
    }
    while (codeFile1 >> readWord) {
        Sentence sentence(readWord, _legalSymbolNames, _beginSymbolName);
        _sentences.push_back(sentence);
    }
}

void Grammar::insertLegalSymbolNames(string nameString, bool isTerminal) {
    _legalSymbolNames[nameString] = isTerminal;
}

Symbol::Symbol() {
    _isTerminal = false;
    _isSpace = false;
    _isBegin = false;
    _symbolNumber = 0;
    _row = 0;
    _col = 0;
}

Symbol::Symbol(string symbolName, bool isTerminal, string beginString) {
    _symbolName = symbolName;
    _isTerminal = isTerminal;
    if (symbolName == "?") {
        _isSpace = true;
    } else {
        _isSpace = false;
    }
    if (symbolName == beginString) {
        _isBegin = true;
    } else {
        _isBegin = false;
    }
    _symbolNumber = 0;
    _row = 0;
    _col = 0;
//    _value["f"] = 0;
//    _value["val"] = 0;
}

Symbol::Symbol(string symbolName, bool isTerminal, string beginString, int symbolNumber, int row, int col) {
    _symbolName = symbolName;
    _isTerminal = isTerminal;
    if (symbolName == "?") {
        _isSpace = true;
    } else {
        _isSpace = false;
    }
    if (symbolName == beginString) {
        _isBegin = true;
    } else {
        _isBegin = false;
    }
    _symbolNumber = symbolNumber;
    _row = row;
    _col = col;
}

Sentence::Sentence() {

}

Sentence::Sentence(Symbol leftPart, vector<Symbol> rightPart) {
    _leftPart = leftPart;
    _rightPart = rightPart;
}

Sentence::Sentence(string sentenceString, map<string, bool> legalSymbolNames, string beginString) {
    _sentenceString = sentenceString;
    _legalSymbolNames = legalSymbolNames;
    _beginString = beginString;
    //分割句子字符串
    divideSentenceString();
}

void Sentence::divideSentenceString() {
    string leftPartString;
    string rightPartString;
    bool flag = false;
    for (int i = 0; i < _sentenceString.size(); i++) {
        //根据->分左部右部
        if (_sentenceString[i] == '-' && !flag) {
            if (i != _sentenceString.size() - 1) {
                if (_sentenceString[i + 1] == '>') {
                    flag = true;
                    i++;
                    continue;
                }
            }
        }
        if (!flag) {
            leftPartString = leftPartString + _sentenceString[i];
        } else {
            rightPartString = rightPartString + _sentenceString[i];
        }
    }
    _leftPart = Symbol(leftPartString, false, _beginString);
    //分离右部
    divideRightPart(rightPartString);
}

void Sentence::divideRightPart(string rightPartString) {
    string oneString;
    vector<string> attributeStrings;
    divideAttributeAndSymbol(rightPartString, attributeStrings);
    //如果右部字符串可以在合法符号名集合中找到，直接把右部整体构造为符号对象
    if (_legalSymbolNames.find(rightPartString) != _legalSymbolNames.end()) {
        Symbol symbol(rightPartString, _legalSymbolNames[rightPartString], _beginString);
        _rightPart.push_back(symbol);
        return;
    }
    //否则对右部进行细分
    int i = 0;
    for (string::iterator it = rightPartString.begin(); it != rightPartString.end(); it++, i++) {
        oneString += (*it);
        if (oneString == ":") {
            if (rightPartString[i + 1] == '=') {
                continue;
            }
        }
        if (_legalSymbolNames.find(oneString) != _legalSymbolNames.end()) {
            Symbol symbol(oneString, _legalSymbolNames[oneString], _beginString);
            _rightPart.push_back(symbol);
            oneString.clear();
        }
    }
}

void Sentence::divideAttributeAndSymbol(string rightPartString, vector<string> &attributeStrings) {
    string attributeString;
    string symbolString;
    bool flag = false;
    for (int i = 0; i < rightPartString.size(); i++) {
        if (rightPartString[i] == '{') {
            flag = true;
            if (!symbolString.empty()) {
                Symbol symbol(symbolString, _legalSymbolNames[symbolString], _beginString);
                _rightPart.push_back(symbol);
                symbolString.clear();
            }
            continue;
        }
        if (rightPartString[i] == '}') {
            flag = false;
            attributeStrings.push_back(attributeString);
            attributeString.clear();
            continue;
        }
        if (flag) {
            attributeString += rightPartString[i];
            continue;
        }
        symbolString += rightPartString[i];
    }
}

//void Sentence::attributeStrings2Attribute(vector<string> attributeStrings) {
//    string oneString;
//    for (int i = 0; i < attributeStrings.size() - 1; i++) {
//        for (int j = 0; j < attributeStrings[i].size(); j++) {
//            if()
//        }
//    }
//}
Tree::Tree(Symbol data) {
    _data = data;
}

//Tree::Tree(Symbol data, vector<Tree> *nodes) {
//    _data = data;
//    _nodes = nodes;
//}

